
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Tama_Chan.AI;
using Tama_Chan.GameEngine_ns;
using System.Linq;
using Tama_Chan.Utils;


namespace Tama_Chan.ParticleEngine_ns
{

   public class ParticleEngine
   {
      public IList<IParticleEffect> ParticleEffects { get; set; }
      private GameEngine GameEngine { get; set; }
      private Texture2D EmptyRing { get; set; }
      private Texture2D Star { get; set; }
      private Texture2D Rays { get; set; }


      public ParticleEngine(GameEngine gameEngine)
      {
         ParticleEffects = new List<IParticleEffect>();
         GameEngine = gameEngine;
      }


      public void Initialize()
      {
         // ...
      }


      public void LoadContent()
      {
         EmptyRing = GameEngine.Game1.Content.Load<Texture2D>(@"Images\emptyRing");
         Star = GameEngine.Game1.Content.Load<Texture2D>(@"Images\star20x20");
         Rays = GameEngine.Game1.Content.Load<Texture2D>(@"Images\rays");
      }


      public void Update(GameTime gameTime)
      {
         for(int i=0; i<ParticleEffects.Count; i++)
         {
            IParticleEffect particleEffect = ParticleEffects[i];
            particleEffect.Update(gameTime);
            if(particleEffect.IsDead)
            {
               ParticleEffects.Remove(particleEffect);
            }
         }
      }


      public void Draw()
      {
         foreach(var particleEffect in ParticleEffects)
         {
            particleEffect.Draw();
         }
      }


      public void CreateExpandingRingEffect(GameTime gameTime, Vector2 position, float depth)
      {
         var particleEffect = new ParticleEffect(3);
         particleEffect.AddParticle(new ScalingParticle(GameEngine.Game1.SpriteBatch,
                                                        gameTime.TotalGameTime.Ticks,
                                                        0L,           // Activation Delay in ticks
                                                        EmptyRing,    // Texture
                                                        position,     // Position
                                                        Vector2.Zero, // Acceleration
                                                        Color.Orange, // Color
                                                        .1f,          // Starting scale
                                                        1.0f,         // How fast scale changes per second
                                                        1.0f,         // Scale limit
                                                        true,         // IsExpanding
                                                        depth));      // Depth

         particleEffect.AddParticle(new ScalingParticle(GameEngine.Game1.SpriteBatch,
                                                        gameTime.TotalGameTime.Ticks,
                                                        TimeSpan.TicksPerSecond / 4L,
                                                        EmptyRing,
                                                        position,
                                                        Vector2.Zero,
                                                        Color.Orange,
                                                        .1f,
                                                        2.0f,
                                                        1.0f,
                                                        true,
                                                        depth));

         particleEffect.AddParticle(new ScalingParticle(GameEngine.Game1.SpriteBatch,
                                                        gameTime.TotalGameTime.Ticks,
                                                        TimeSpan.TicksPerSecond / 2L,
                                                        EmptyRing,
                                                        position,
                                                        Vector2.Zero,
                                                        Color.Orange,
                                                        .1f,
                                                        4.0f,
                                                        1.0f,
                                                        true,
                                                        depth));

         ParticleEffects.Add(particleEffect);
      }


      public void CreateTeleporterEffect(GameTime gameTime, Vector2 position, bool isExpanding)
      {
         var particleEffect = new ParticleEffect(1);
         particleEffect.AddParticle(new ScalingParticle(GameEngine.Game1.SpriteBatch,
                                                        gameTime.TotalGameTime.Ticks,
                                                        0L,
                                                        EmptyRing,
                                                        position,
                                                        Vector2.Zero,
                                                        Color.DeepSkyBlue,
                                                        isExpanding ? .1f : 1.5f, // Initial scale
                                                        isExpanding ? 1f : -1f, // Rate
                                                        isExpanding ? 1.5f : .1f, // Scale limit
                                                        isExpanding,
                                                        GameEngine.ParticleDepth));

         ParticleEffects.Add(particleEffect);
      }


      public void CreateSpawnEffect(GameTime gameTime, Vector2 position, Color color)
      {
         var particleEffect = new ParticleEffect(1);
         particleEffect.AddParticle(new RotatingParticle(GameEngine.Game1.SpriteBatch,
                                                         gameTime,
                                                         0L,
                                                         GeneralUtils.GetSecondsAsTicks(2L),
                                                         Rays,
                                                         position,
                                                         Vector2.Zero,
                                                         color,
                                                         MathHelper.Pi,
                                                         GameEngine.ParticleDepth, 
                                                         3f));
         ParticleEffects.Add(particleEffect);
      }


      public void CreateExplosionEffect(GameTime gameTime, Vector2 position, int minParticles, int maxParticles)
      {
         var random = new Random();

         int numParticles = random.Next(minParticles, maxParticles);
         var particleEffect = new ParticleEffect(numParticles);

         const float minRotationRate = MathHelper.TwoPi;
         const float maxRotationRate = MathHelper.TwoPi * 10f;

         // Raise these by 1000 to knock off the decimal places
         const int minRotationRateRaised = (int)(minRotationRate * 1000f);
         const int maxRotationRateRaised = (int)(maxRotationRate * 1000f);

         const int minSpeed = 1;
         const int maxSpeed = 4;

         for(int i=0; i<numParticles; i++)
         {
            // Get the random rotation raised and divide by the same amount to put back as it was.
            float rotationRate = random.Next(minRotationRateRaised, maxRotationRateRaised) / 1000f;
            const long activationDelay = 0L;
            long lifeTime = GeneralUtils.GetSecondsAsTicks(1);
            int speed = random.Next(minSpeed, maxSpeed);
            Vector2 velocity = AIUtils.GetRandomVelocity(speed, random);
            Color color = new Color(random.Next(50, 200), random.Next(50, 200), random.Next(50, 200));

            var particle = new RotatingParticle(GameEngine.Game1.SpriteBatch,
                                                gameTime,
                                                activationDelay,
                                                lifeTime,
                                                Star,
                                                position,
                                                velocity,
                                                color,
                                                rotationRate,
                                                GameEngine.ParticleDepth, 
                                                1f);
            particleEffect.AddParticle(particle);
         }

         ParticleEffects.Add(particleEffect);
      }

   }
}
